----------------------------------------------------------------------------------
-- Company: 
-- Engineer: 
-- 
-- Create Date:	   13:09:14 04/07/2009 
-- Design Name: 
-- Module Name:	   register - Behavioral 
-- Project Name: 
-- Target Devices: 
-- Tool versions: 
-- Description: 
--
-- Dependencies: 
--
-- Revision: 
-- Revision 0.01 - File Created
-- Additional Comments: 
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.STD_LOGIC_ARITH.all;
use IEEE.STD_LOGIC_SIGNED.all;

---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity CPU_register is
  generic(
    N		 : integer := 32;
    Has_RE	 : integer := 0;
    Has_OE	 : integer := 1;
    Has_MemRead	 : integer := 1;
    Has_MemWrite : integer := 1
    );
  port (CLK_IN	     : in  std_logic;
	 RE_IN	     : in  std_logic := '0';
	 OE_IN	     : in  std_logic := '0';
	 BusData_IN  : in  std_logic_vector (N-1 downto 0);
	 BusData_OUT : out std_logic_vector (N-1 downto 0);
	 mem_RE	     : in  std_logic := '0';
	 MemData_IN  : in  std_logic_vector (N-1 downto 0) := (others => '0');
	 MemData_OUT : out std_logic_vector (N-1 downto 0);
	 debug : out std_logic_vector(N-1 downto 0)
	 );
end CPU_register;

architecture Behavioral of CPU_register is
  signal content : std_logic_vector(N-1 downto 0) := (others => '0');
begin
  -- Output enable
  BUS_OE : if Has_OE = 1 generate
    with OE_IN select
      BusData_OUT <= content when '1',
      (others => 'Z')	     when others;
  end generate;

  NO_BUS_OE : if Has_OE = 0 generate
    BusData_OUT <= content;
  end generate;

  --Write enable is sent to the memmory instead, otherwise we would hold the value using a flipflop
  MEM_OE : if Has_MemWrite = 1 generate
    MemData_OUT <= content;
  end generate;
  
  debug <= content;

  process(CLK_IN)
  begin
    if(CLK_IN = '1' and CLK_IN'event) then
      -- Latch Input
      content <= content;

      if(Has_MemRead = 1) then
	if(mem_RE = '1') then
	  content <= MemData_IN;
	end if;
      end if;

      if(Has_RE = 1) then
	if(RE_IN = '1') then
	  content <= BusData_IN;
	end if;
      end if;
    end if;
  end process;
end Behavioral;

